<?php


namespace app\admin\controller;


use app\admin\model\AuthGroup;
use app\admin\model\FlowNumber;
use app\admin\model\Output;
use app\admin\model\Scheme;
use app\BaseController;
use app\Request;
use fast\Tree;

use think\console\Input;
use think\db\exception\PDOException;
use think\Exception;
use think\exception\ValidateException;
use think\facade\Config;
use think\facade\Db;
use think\facade\Validate;
use think\facade\View;

class Design extends BaseController
{
    /**
     * @var \app\admin\model\Admin
     */
    protected $childrenGroupIds = [];
    protected $childrenAdminIds = [];
    protected $group = [];
    protected $role_id;
    protected $model = null;
    protected $number = null;

    public function initialize()
    {
        parent::initialize();

        $this->childrenAdminIds = $this->auth->getChildrenAdminIds(true);
        $this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);
        $this->model = new Scheme();
        $this->number = new FlowNumber();
        $groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();

        Tree::instance()->init($groupList);
        $groupdata = [];
        if ($this->auth->isSuperAdmin()) {
            $result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
            foreach ($result as $k => $v) {
                $groupdata[$v['id']] = $v['name'];
            }
        } else {
            $result = [];
            $groups = $this->auth->getGroups();
            foreach ($groups as $m => $n) {
                $this->role_id = $n['id'];
                $childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
                $temp = [];
                foreach ($childlist as $k => $v) {
                    $temp[$v['id']] = $v['name'];
                }
                $result[($n['name'])] = $temp;
            }
            $groupdata = $result;
        }
        $this->group = $groupdata;
    }

    public function index(Request $request)
    {

        if ($request->isAjax()) {
            //获取每页显示的条数
            $limit = $request->param('limit');
            //获取当前页数
            $page = $request->param('page');
            $result = $this->model->paginate($limit, false, ['page' => $page])->toArray();

            return json(['code' => 200, 'msg' => '', 'total' => $result['total'], 'data' => $result['data']]);
        }


        return View::fetch();
    }


    //新增
    public function add(Request $request)
    {
        if ($request->isAjax()) {
            $data = $request->param();
            $bizScheme = 'flow_' . $data['flowcode'];
            $data['bizscheme'] = $bizScheme;
            if ($data) {
                if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                    $params[$this->dataLimitField] = $this->auth->id;
                }
                try {
                    $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                    $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                    validate(\app\admin\validate\Scheme::class)->scene('add')->check($data);

                    $result = $this->model->replace()->save($data);
                    $result = $this->number->replace()->save(['code' => $data['flowcode'], 'year' => $data['year'], 'month' => $data['month'], 'lengh' => $data['lengh'], 'pre' => $data['pre'], 'index' => 0]);
                    if ($result !== false) {
                        $sql = "DROP TABLE IF EXISTS $bizScheme";
                        Db::execute($sql);
                        $sql = "CREATE TABLE $bizScheme ( id char(36) primary key ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT";
                        Db::execute($sql);
                        return json(['code' => 200, 'url' => '', 'msg' => '成功！']);
                    } else {
                        $this->error($this->model->getError());
                    }
                } catch (ValidateException $e) {
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    $this->error($e->getMessage());
                }
            }

        }
        return View::fetch();
    }

    public function from(Request $request)
    {
        $model = $request->param();

        View::assign('model', $model);
        return View::fetch();
    }

    //获取用户
    public function selectrolepageUser(Request $request)
    {
        //设置过滤方法
        $request->filter(['strip_tags', 'htmlspecialchars']);

        //搜索关键词,客户端输入以空格分开,这里接收为数组
        $word = (array)$request->param("q_word/a");
        //当前页
        $page = $request->param("pageNumber");
        //分页大小
        $pagesize = $request->param("pageSize");
        //搜索条件
        $andor = $request->param("andOr", "and", "strtoupper");
        //排序方式
        $orderby = (array)$request->param("orderBy/a");
        //显示的字段
        $field = $request->param("showField");
        //主键
        $primarykey = $request->param("keyField");
        //主键值
        $primaryvalue = $request->param("keyValue");
        //搜索字段
        $searchfield = (array)$request->param("searchField/a");
        //自定义搜索条件
        $custom = (array)$request->param("custom/a");
        //如果有primaryvalue,说明当前是初始化传值
        if ($primaryvalue !== null) {
            $where[] = array($primarykey, 'in', $primaryvalue);
            $pagesize = 99999;
        } else {
            $where[] = function ($query) use ($word, $andor, $field, $searchfield, $custom) {
                $logic = $andor == 'AND' ? '&' : '|';
                $searchfield = is_array($searchfield) ? implode($logic, $searchfield) : $searchfield;
                foreach ($word as $k => $v) {
                    $query->where(str_replace(',', $logic, $searchfield), "like", "%{$v}%");
                }
                if ($custom && is_array($custom)) {
                    foreach ($custom as $k => $v) {
                        if (is_array($v) && 2 == count($v)) {
                            $query->where($k, trim($v[0]), $v[1]);
                        } else {
                            $query->where($k, '=', $v);
                        }
                    }
                }
            };
        }
        $data = [];
        $admin = \app\admin\model\Admin::where($where)->select();
        foreach ($admin as $k1 => $v1) {
            $data[]['id'] = $v1['id'];
            $data[$k1]['username'] = $v1['nickname'];
            $data[$k1]['pid'] = 0;
        }
        $info = [
            'list' => $data,
            'total' => count($data)
        ];
        return ($info);
    }

    //获取角色
    public function selectrolepageRole(Request $request)
    {
        //设置过滤方法
        $request->filter(['strip_tags', 'htmlspecialchars']);

        //搜索关键词,客户端输入以空格分开,这里接收为数组
        $word = (array)$request->param("q_word/a");
        //当前页
        $page = $request->param("pageNumber");
        //分页大小
        $pagesize = $request->param("pageSize");
        //搜索条件
        $andor = $request->param("andOr", "and", "strtoupper");
        //排序方式
        $orderby = (array)$request->param("orderBy/a");
        //显示的字段
        $field = $request->param("showField");
        //主键
        $primarykey = $request->param("keyField");
        //主键值
        $primaryvalue = $request->param("keyValue");
        //搜索字段
        $searchfield = (array)$request->param("searchField/a");
        //自定义搜索条件
        $custom = (array)$request->param("custom/a");
        //如果有primaryvalue,说明当前是初始化传值
        if ($primaryvalue !== null) {
            $where[] = array($primarykey, 'in', $primaryvalue);
            $pagesize = 99999;
        } else {
            $where[] = function ($query) use ($word, $andor, $field, $searchfield, $custom) {
                $logic = $andor == 'AND' ? '&' : '|';
                $searchfield = is_array($searchfield) ? implode($logic, $searchfield) : $searchfield;
                foreach ($word as $k => $v) {
                    $query->where(str_replace(',', $logic, $searchfield), "like", "%{$v}%");
                }
                if ($custom && is_array($custom)) {
                    foreach ($custom as $k => $v) {
                        if (is_array($v) && 2 == count($v)) {
                            $query->where($k, trim($v[0]), $v[1]);
                        } else {
                            $query->where($k, '=', $v);
                        }
                    }
                }
            };
        }
        $list = AuthGroup::where($where)->page(intval($page), intval($pagesize))->select();
        $data = [];
        foreach ($list as $k1 => $v1) {
            $data[]['id'] = $v1['id'];
            $data[$k1]['name'] = $v1['name'];
            $data[$k1]['pid'] = 0;
        }
        $info = [
            'list' => $data,
            'total' => count($data)
        ];
        return ($info);
    }


    //流程图设计
    public function design(Request $request)
    {
        $id = $request->param('id');
        $row = Scheme::find($id);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if ($request->isAjax()) {
            $params = $request->param();
            if ($params) {
                $params = $this->preExcludeFields($params);
                $result = false;
                Db::startTrans();
                try {
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                        $row->validateFailException(true)->validate($validate);
                    }
                    $result = $row->save($params);
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }

        View::assign("row", $row);
        View::assign("id", $id);
        View::assign("flowcontent", $row->flowcontent);
        return View::fetch();
    }


    //点击流程图链接线触发
    public function line(Request $request)
    {
        $ids = $request->param('ids');
        if ($request->isAjax()) {
            $ids = $request->param('ids');
            $scheme = Scheme::find($ids);

            //从数据库中获取表字段信息
            $sql = "SELECT COLUMN_KEY,COLUMN_NAME,COLUMN_TYPE,COLUMN_COMMENT,COLUMN_DEFAULT FROM `information_schema`.`columns` "
                . "WHERE TABLE_SCHEMA = ? AND table_name = ? "
                . "ORDER BY ORDINAL_POSITION";
            //加载主表的列
            $dbname = Config::get('database.connections.mysql.database');
            $columnList = Db::query($sql, [$dbname, $scheme['bizscheme']]);

            $list = collection($columnList)->toArray();

            foreach ($list as $k => $v) {
                $state = ['opened' => true];
                $tree[] = [
                    'id' => $v['COLUMN_NAME'],
                    'parent' => '1',
                    'title' => $v['COLUMN_NAME'],
                    'type' => 'list',
                    'spread' => $state
                ];
            }
            $channelList[] = [
                'id' => '1',
                'parent' => '#',
                'title' => '列表',
                'type' => 'list',
                'spread' => $state,
                'children' => $tree
            ];
            return json($channelList);
        }
        View::assign("ids", $ids);
        return View::fetch();
    }


    public function del($ids = "")
    {
        $model = new Scheme();
        if ($ids) {
            $pk = $model->getPk();

            $adminIds = $this->getDataLimitAdminIds();
            if (is_array($adminIds)) {
                $count = $model->where($this->dataLimitField, 'in', $adminIds);
            }
            $list = $model->where($pk, 'in', $ids)->select();

            foreach ($list as $k => $v) {
                Scheme::destroy(function ($query) use ($v) {
                    $query->where('id', '=', $v['id']);
                }, true);
                $flowcode = $v['flowcode'];;
                $table = $v['bizscheme'];
                Db::name('flow_number')->where(['code' => $flowcode])->delete();
                if ($v['isenable'] == '1') {
                    //生成curd
                    $commandtype = 'FlowCrud';
                    $table = $v['bizscheme'];
                    $argv = array("--table=$table", "--delete=1", "-force=1");

                    $commandName = "\\app\\admin\\command\\" . ucfirst($commandtype);

                    $input = new Input($argv);

                    $output = new Output();
                    $command = new $commandName($commandtype);

                    $data = [
                        'type' => $commandtype,
                        'params' => json_encode($argv),
                        'command' => "php think {$commandtype} " . implode(' ', $argv),
                        'executetime' => time(),
                    ];

                    $command->run($input, $output);

                    $result = implode("\n", $output->getMessage());
                }

                if ($table) {
                    $sql = "DROP TABLE IF EXISTS $table";
                    Db::execute($sql);
                }
            }
        }
        return json(['code' => 200, 'url' => '', 'msg' => '成功']);
    }

}